package manage.matcher;

import entity.Admin;
import manage.service.AdminService;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.concurrent.atomic.AtomicInteger;

public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher {

    @Autowired
    private AdminService adminService;

    private Cache<String, AtomicInteger> passwordRetryCache;

    public RetryLimitHashedCredentialsMatcher(CacheManager cacheManager) {
        passwordRetryCache = cacheManager.getCache("passwordRetryCache");
    }

    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {

        //获取用户名
        String username = (String)token.getPrincipal();
        //获取用户登录次数
        AtomicInteger retryCount = passwordRetryCache.get(username);
        if (retryCount == null) {
            //如果用户没有登陆过,登陆次数加1 并放入缓存
            retryCount = new AtomicInteger(0);
            passwordRetryCache.put(username, retryCount);
        }
        //如果次数超过5直接抛出异常
        if (retryCount.get() >= 5){
            throw new LockedAccountException("该账户已被锁定半小时...");
        }
        //判断用户账号和密码是否正确
        boolean matches = super.doCredentialsMatch(token, info);
        if (matches) {
            Admin admin = adminService.login(username);
            if (admin.getAvailable() == -1){
                throw new LockedAccountException("该用户已被锁定...");
            }
            //如果正确,从缓存中将用户登录计数 清除
            passwordRetryCache.remove(username);
        }else {
            retryCount.incrementAndGet();
            passwordRetryCache.put(username, retryCount);
            if (retryCount.intValue() > 5) {
                //如果用户登陆失败次数大于5次 抛出锁定用户异常  并修改数据库字段
//                Admin admin = adminService.login(username);
//                if (admin != null && admin.getAvailable() != -1){
//                    //修改数据库的状态字段为锁定
//                    adminService.lock(admin.getId());
//                }
                //抛出用户锁定异常
                throw new LockedAccountException("该用户已被锁定半小时...");
            }
            throw new IncorrectCredentialsException("密码错误,您还能尝试"+(5-retryCount.intValue())+"次");
        }
        return true;
    }

    /**
     * 根据用户名 解锁用户
     * @param username
     * @return
     */
    /*public void unlockAccount(String username){
        passwordRetryCache.remove(username);
    }*/
}
